/*
 * Copyright (c) 2011 Joe Kopena <tjkopena@gmail.com>
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
*/

package com.rocketshipgames.haxe.gfx.primitives;

import com.rocketshipgames.haxe.World;

import flash.text.TextField;
import flash.text.TextFormat;
import flash.text.TextLineMetrics;
import flash.display.BitmapData;
import flash.geom.Point;
import flash.geom.Rectangle;

import com.rocketshipgames.haxe.gfx.Graphic;
import com.rocketshipgames.haxe.AssetCache;

enum HorizontalJustification {
  TEXT_CENTER;
  TEXT_LEFT;
  TEXT_RIGHT;
}

enum VerticalJustification {
  TEXT_MIDDLE;
  TEXT_TOP;
  TEXT_BOTTOM;
}

class TextSettings {
  public var hjustification:HorizontalJustification;
  public var vjustification:VerticalJustification;

  public var colorV:Int;
  public var sizeV:Float;
  public var fontV:String;
  public var bgcolorV:Int;

  public var colorT:Bool;
  public var sizeT:Bool;
  public var fontT:Bool;


  public function new():Void
  {
    hjustification = TEXT_CENTER;
    vjustification = TEXT_MIDDLE;
    bgcolorV = 0x00;
    colorT = false;
    colorV = 0xff000000;
    sizeT = false;
    sizeV = 24;
    fontT = true;
    fontV = "Nokia Cellphone FC";
    // end function new
  }

  public function align(j:HorizontalJustification):TextSettings
  { hjustification = j; return this; }

  public function valign(j:VerticalJustification):TextSettings
  { vjustification = j; return this; }

  public function color(c:Int):TextSettings
  { colorT = true; colorV = c; return this; }

  public function size(s:Float):TextSettings
  { sizeT = true; sizeV = s; return this; }

  public function clearFont():TextSettings
  { fontT = false; fontV = null; return this; }

  public function font(f:String):TextSettings
  { fontT = true; fontV = f; return this; }

  public function bgcolor(c:Int):TextSettings
  { bgcolorV = c; return this; }

  public function newTextFormat():TextFormat
  {
    var ts:TextFormat = new TextFormat();
    if (colorT)
      ts.color = colorV;

    if (sizeT)
      ts.size = sizeV;

    if (fontT) {
      ts.font = fontV;
      trace("Set font to " + ts.font);
    }

    return ts;
    // end function newTextFormat
  }
  // end class TextSettings
}

class Text implements Graphic {

  private var _bitmap:BitmapData;
  private var _point:Point;
  private var _rect:Rectangle;

  public var width:Float;
  public var height:Float;

  private var _xoff:Float;
  private var _yoff:Float;

  private var _text:String;
  private var _tf:TextField;

  /*
  private var _horizontalJustification:HorizontalJustification;
  private var _verticalJustification:VerticalJustification;
  */

  public function new(text:String, ?opts:TextSettings=null):Void
  {
    if ((_tf = new TextField()) == null) {
      trace("ERROR: Could not create TextField.");
      return;
    }

    if (opts == null)
      opts = new TextSettings();

    //-- Configure options --

    //-- Create the bitmap
    _tf.text = _text = text;
    if (opts.fontT)
      _tf.embedFonts = true;
    _tf.setTextFormat(opts.newTextFormat());

    _tf.width = width = _tf.textWidth + 4;
    _tf.height = height = _tf.textHeight + 4;

    /*
    height = 0;
    width = 0;
    var i:Int = 0;
    while (i < _tf.numLines) {
      var tlm:TextLineMetrics = _tf.getLineMetrics(i);
      height += tlm.ascent + tlm.descent + tlm.leading;
      width += Math.max(width, tlm.width);
      i++;
    }
    _tf.width = width;
    _tf.height = height;
    */

    trace("w,h " + width + "," + height);

    _bitmap = new BitmapData(Std.int(width)+4, Std.int(height)+4);
    if (_bitmap == null) {
      trace("ERROR: Null bitmap data for Text.");
      return;
    }

    _point = new Point(0, 0);
    _rect = new Rectangle(0, 0, width, height);

    _bitmap.fillRect(_rect, opts.bgcolorV);

    _bitmap.draw(_tf);

    switch (opts.hjustification) {
    case TEXT_CENTER: _xoff = -width/2;
    case TEXT_LEFT: _xoff = 0;
    case TEXT_RIGHT: _xoff = -width;
    }
    switch (opts.vjustification) {
    case TEXT_MIDDLE: _yoff = -height/2;
    case TEXT_TOP: _yoff = 0;
    case TEXT_BOTTOM: _yoff = -height;
    }

    // end function new
  }

  //------------------------------------------------------------
  public function render(x:Float, y:Float):Void
  {
    _point.x = x+_xoff;
    _point.y = y+_yoff;
    World.buffer.copyPixels(_bitmap, _rect, _point, null, null, true);
    // end function render
  }

  // end class Text
}
